<template>
  <el-card>
    <el-form
      label-width="100px"
      :model="travelParams"
      :rules="rules"
      ref="travelForm"
    >
      <el-form-item label="景点名称" prop="name" required>
        <el-input
          placeholder="请输入景点名称"
          v-model="travelParams.name"
        ></el-input>
      </el-form-item>
      <el-form-item label="景点分类" prop="category" required>
        <el-input
          placeholder="请输入景点分类"
          v-model="travelParams.category"
        ></el-input>
      </el-form-item>

      <el-form-item label="景点平均价格" prop="price" required>
        <el-input
          style="width: 250px"
          placeholder="景点平均价格"
          type="number"
          v-model="travelParams.price"
        ></el-input>
      </el-form-item>
      <el-form-item label="景点描述" required prop="introduction">
        <el-input
          type="textarea"
          placeholder="请输入景点描述"
          v-model="travelParams.introduction"
        ></el-input>
      </el-form-item>
      <el-form-item label="景点联系电话" required prop="phone">
        <el-input
          placeholder="请输入景点联系电话"
          v-model="travelParams.phone"
        ></el-input>
      </el-form-item>

      <el-form-item label="景点地址" required prop="location">
        <el-input
          placeholder="景点地址"
          style="margin-right: 10px; width: 80%"
          v-model="travelParams.location"
          @change="getLocation"
        ></el-input>
        <el-button type="primary" icon="search" @click="search">搜索</el-button>
        <el-button v-show="!travelParams.id" type="default" @click="reset">
          重置
        </el-button>
        <baidu-map
          style="margin-top: 10px"
          v-show="showMap"
          class="map"
          :center="center"
          :zoom="zoom"
          :scroll-wheel-zoom="true"
          mapType="BMAP_HYBRID_MAP"
          @moving="syncCenterAndZoom"
          @moveend="syncCenterAndZoom"
          @zoomend="syncCenterAndZoom"
          @click="mapClick($event)"
        >
          <bm-marker
            v-show="travelParams.id"
            :position="marker"
            :dragging="true"
            animation="BMAP_ANIMATION_DROP"
            @dragend="markerClick($event)"
          ></bm-marker>
        </baidu-map>
      </el-form-item>

      <el-form-item label="景点封面图片">
        <el-upload
          v-model:file-list="coverList"
          action="/admin/admin/travel/upload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :before-upload="handlerUpload"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img
            w-full
            :src="dialogImageUrl"
            style="width: 100%; height: 100%"
            alt="Preview Image"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="景点详情图片">
        <el-upload
          v-model:file-list="imagesList"
          action="/admin/admin/travel/upload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview1"
          :on-remove="handleRemove"
          :before-upload="handlerUpload"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible1">
          <img
            w-full
            :src="dialogImageUrl1"
            style="width: 100%; height: 100%"
            alt="Preview Image"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="景点视频">
        <el-upload
          v-model:file-list="videoList"
          style="width: 300px"
          class="upload-demo"
          drag
          action="/admin/admin/travel/upload"
          multiple
          :before-upload="uploadVedio"
          :on-remove="handleRemove"
          :limit="1"
          :on-preview="previewVideo"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            拖拽上传或
            <em>点击上传</em>
          </div>
        </el-upload>
        <el-dialog v-model="dialogVisible2">
          <video
            w-full
            :src="dialogVideoUrl2"
            style="width: 100%; height: 100%"
            controls
            preload="auto"
            ref="videoRef"
            @play="isPlaying = true"
            @pause="isPlaying = false"
          ></video>
        </el-dialog>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" size="default" @click="save">保存</el-button>
        <el-button type="default" size="default" @click="cancel">
          取消
        </el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { nextTick, ref } from 'vue'
import { useGeocoder, usePoint } from 'vue-baidu-map-3x'
import type { Travel } from '@/api/front/travel/type'
import { UploadFilled } from '@element-plus/icons-vue'
import {
  reqAddOrUpdateTravel,
  reqDeleteMedia,
  reqGetMedia,
} from '@/api/front/travel'

let $emit = defineEmits(['changeScene'])

// 表单变量
let coverList = ref([])
let imagesList = ref([])
let videoList = ref([])
let dialogImageUrl = ref('')
let dialogImageUrl1 = ref('')
let dialogVideoUrl2 = ref('')
let dialogVisible = ref(false)
let dialogVisible1 = ref(false)
let dialogVisible2 = ref(false)
let videoRef = ref()
let isPlaying = ref(false)
let travelForm = ref()
// 定义地图变量
let showMap = ref<boolean>(false)
let zoom = ref(13)
//存储美食对象
let travelParams = ref<Travel>({
  name: '',
  category: '',
  price: 0,
  introduction: '',
  location: '',
  latitude: 0,
  longitude: 0,
  phone: '',
  rating: 0,
  is_online: 0,
  id: 0,
  cover: [],
  images: [],
  video: [],
})
// 地图中心点坐标
const center = ref({
  lat: 0,
  lng: 0,
})
// marker坐标
const marker = ref({ lat: 0, lng: 0 })
// 通过输入地址获取经纬度函数
const getLocation = () => {
  useGeocoder().then((geocoder: any) => {
    geocoder.getPoint(travelParams.value.location, (res: any) => {
      center.value = {
        lng: res.lng,
        lat: res.lat,
      }
      marker.value = {
        lng: res.lng,
        lat: res.lat,
      }
    })
  })
  showMap.value = true
  zoom.value = 18
}

// 地址栏搜索、重置
const search = () => {
  if (travelParams.value.location) {
    getLocation()
  } else {
    ElMessage.warning('请输入地址')
  }
}
const reset = () => {
  travelParams.value.location = ''
  showMap.value = false
}
const syncCenterAndZoom = (e: any) => {
  // 获取地图中心点的经纬度
  const { lng, lat } = e.target.getCenter()

  // 获取地图的缩放级别
  zoom.value = e.target.getZoom()

  // 在下一个渲染周期后更新中心点坐标
  nextTick(() => {
    center.value.lng = lng
    center.value.lat = lat
  })
}
// 标点拖拽
const markerClick = (e: any) => {
  const res = e.point
  useGeocoder().then((geocoder: any) => {
    usePoint(res.lng, res.lat).then((point: any) => {
      geocoder.getLocation(point, (result: any) => {
        // console.log(result)
        travelParams.value.latitude = result.point.lat
        travelParams.value.longitude = result.point.lng
        travelParams.value.location = result.address + result.content.poi_desc
      })
    })
  })
}
// 地图点击事件
const mapClick = (e: any) => {
  const res = e.point
  useGeocoder().then((geocoder: any) => {
    usePoint(res.lng, res.lat).then((point: any) => {
      geocoder.getLocation(point, (result: any) => {
        // console.log(result)
        travelParams.value.latitude = result.point.lat
        travelParams.value.longitude = result.point.lng
        travelParams.value.location = result.address + result.content.poi_desc
        marker.value.lat = result.point.lat
        marker.value.lng = result.point.lng
      })
    })
  })
}
// 将收集还未选择的销售属性的ID与属性值的名字
// let saleAttrIdAndValueName = ref<string>('')
// 取消按钮的点击事件
const cancel = () => {
  $emit('changeScene', { flag: 1, params: 'update' })
}
// 封面照片墙点击预览按钮时候的触发钩子
const handlePictureCardPreview = (file: any) => {
  dialogImageUrl.value = file.url
  dialogVisible.value = true
}
// 介绍照片墙点击预览按钮时候的触发钩子
const handlePictureCardPreview1 = (file: any) => {
  dialogImageUrl1.value = file.url
  dialogVisible1.value = true
}
// 预览视频前的钩子
const previewVideo = (file: any) => {
  dialogVideoUrl2.value = file.response.data[0]
  dialogVisible2.value = true
}
// 移除图片前的钩子
const handleRemove = async (file: any) => {
  const img =
    file.response && file.response.data
      ? file.response.data[0].split('/').pop().split('\\').pop()
      : file.path //图片地址
  await reqDeleteMedia(img)
}

// 上传图片前的钩子
const handlerUpload = (file: any) => {
  if (
    file.type == 'image/jpeg' ||
    file.type == 'image/png' ||
    file.type == 'image/gif'
  ) {
    if (file.size / 1024 / 1024 < 3) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '图片大小不能超过3M',
      })
    }
  } else {
    ElMessage({
      type: 'error',
      message: '图片格式不正确',
    })
    return false
  }
}
// 上传视频前的钩子
const uploadVedio = (file: any) => {
  if (
    file.type === 'video/mp4' ||
    file.type === 'video/webm' ||
    file.type === 'video/ogg' ||
    file.type === 'video/x-msvideo' ||
    file.type === 'video/mpeg' ||
    file.type === 'video/quicktime' ||
    file.type === 'video/x-ms-wmv'
  ) {
    if (file.size / 1024 / 1024 < 100) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '视频大小不能超过100M',
      })
    }
  } else {
    ElMessage({
      type: 'error',
      message: '视频格式不正确',
    })
    return false
  }
}

const rules = {
  name: [{ required: true, message: '请输入景点名称', trigger: 'blur' }],
  category: [{ required: true, message: '请输入景点分类', trigger: 'blur' }],
  price: [{ required: true, message: '请输入景点平均价格', trigger: 'blur' }],
  introduction: [
    { required: true, message: '请输入景点描述', trigger: 'blur' },
  ],
  phone: [
    { required: true, message: '请输入景点联系电话', trigger: 'blur' },
    // 以下是一个简单的手机号码正则表达式，根据实际情况可能需要调整
    {
      pattern: /^1[3-9]\d{9}$/,
      message: '请输入正确的联系电话',
      trigger: 'blur',
    },
  ],
  location: [{ required: true, message: '请输入景点地址', trigger: 'blur' }],
}
const save = async () => {
  await travelForm.value.vaildate(async (vaild: any) => {
    if (vaild) {
      travelParams.value.latitude = marker.value.lat
      travelParams.value.longitude = marker.value.lng
      travelParams.value.cover = coverList.value.map((item: any) => {
        return {
          type: 'image',
          is_cover: 1,
          uid: item.uid,
          name: item.name,
          path:
            item.response && item.response.data
              ? item.response.data[0].split('/').pop().split('\\').pop()
              : item.path, //图片地址
          imgUrl:
            item.response && item.response.data
              ? item.response.data[0]
              : item.url,
          is_show: 0,
        }
      })
      travelParams.value.images = imagesList.value.map((item: any) => {
        return {
          type: 'image',
          is_cover: 0,
          uid: item.uid,
          name: item.name,
          path:
            item.response && item.response.data
              ? item.response.data[0].split('/').pop().split('\\').pop()
              : item.path, //图片地址
          imgUrl:
            item.response && item.response.data
              ? item.response.data[0]
              : item.url,
          is_show: 0,
        }
      })
      travelParams.value.video = videoList.value.map((item: any) => {
        return {
          type: 'video',
          is_cover: 0,
          uid: item.uid,
          name: item.name,
          path:
            item.response && item.response.data
              ? item.response.data[0].split('/').pop().split('\\').pop()
              : item.path, //地址
          is_show: 0,
        }
      })
      let res = await reqAddOrUpdateTravel(travelParams.value)
      if (res.code == 200) {
        ElMessage({
          type: 'success',
          message: travelParams.value.id ? '修改成功' : '添加成功',
        })
        $emit('changeScene', {
          flag: 1,
          params: travelParams.value.id ? 'update' : 'add',
        })
      }
    }
  })
}

// 添加景点初始化
const initAddTravel = () => {
  travelForm.value.resetFields()
  showMap.value = false
  Object.assign(travelParams.value, {
    name: '',
    category: '',
    price: 0,
    introduction: '',
    location: '',
    latitude: 0,
    longitude: 0,
    phone: '',
    rating: 0,
    id: 0,
    cover: [],
    images: [],
    video: [],
  })
}
// 修改景点初始化请求方法
const initHasTravel = async (row: any) => {
  // console.log(row.name)
  showMap.value = true
  travelParams.value = row
  Object.assign(center.value, {
    lng: row.longitude,
    lat: row.latitude,
  })
  Object.assign(marker.value, {
    lng: row.longitude,
    lat: row.latitude,
  })

  zoom.value = 19
  const { code, data } = await reqGetMedia(travelParams.value.id)
  let c = data.filter(
    (item: any) => item.is_cover === 1 && item.type === 'image',
  )
  let i = data.filter(
    (item: any) => item.is_cover === 0 && item.type === 'image',
  )
  let v = data.filter(
    (item: any) => item.is_cover === 0 && item.type === 'video',
  )
  if (code == 200) {
    coverList.value = c.map((item: any) => {
      return {
        name: item.name,
        url: import.meta.env.VITE_SERVE + '/public/uploads/' + item.path,
        path: item.path,
      }
    })
    imagesList.value = i.map((item: any) => {
      return {
        name: item.name,
        url: import.meta.env.VITE_SERVE + '/public/uploads/' + item.path,
        path: item.path,
      }
    })
    videoList.value = v.map((item: any) => {
      return {
        name: item.name,
        path: item.path,
      }
    })
  }
}
defineExpose({ initHasTravel, initAddTravel })
</script>

<style lang="scss" scoped>
/* 地图容器必须设置宽和高属性 */
.map {
  width: 100%;
  height: 500px;
}
</style>
